<template>
    <div class="leader-line-label pointer-none">
        <div class="label-content">
            <span class="location-point"></span>
            <input type="checkbox" name="引线标签" :id="'引线标签选项' + props.Information.InstanceId"
                :value="props.Information.InstanceId" v-model="LabelComponent.Default.Highlighters.value" />
            <label class="content pointer-auto" :for="'引线标签选项' + props.Information.InstanceId">
                <span>{{ props.Information.Name }}</span>
                <span></span>
            </label>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ClientMessage } from '@runtime/generate/message/ClientMessage';
import LabelComponent from '@runtime/UnityEngineBridge/LabelComponent';
import { computed, ComputedRef } from 'vue';

interface Props {
    Information: ClientMessage.LabelInformation;
}

const props = defineProps<Props>();

/**
 * 标签圆角半径
 */
const cornerRadius: number = 0.6;
/**
 * (标签圆角对应矩形对角线长度 - 标签圆角半径) / √2
 */
const cornerEdgeLength: number = (cornerRadius * Math.sqrt(2) - cornerRadius) / Math.sqrt(2);

/**
 * 圆点边长
 */
const pointEdgeLength: number = 3.6;
const pointEdge: string = `${pointEdgeLength}rem`;

/**
 * 指示线长度
 */
const lineLength: ComputedRef<string> = computed(() => `${props.Information.Length}rem`);
/**
 * 指示线角度
 * @description RB 0 45
 * @description LB 1 135
 * @description LT 2 225
 * @description RT 3 315
 */
const lineDirection: ComputedRef<string> = computed(() => `${props.Information.Direction}deg`);

/**
 * 指示线是否在左侧
 */
const left: ComputedRef<boolean> = computed(
    () => props.Information.Direction == 135 || props.Information.Direction == 225
);
/**
 * 指示线是否在顶侧
 */
const top: ComputedRef<boolean> = computed(
    () => props.Information.Direction == 225 || props.Information.Direction == 315
);
/**
 * 指示线是否在右侧
 */
const right: ComputedRef<boolean> = computed(
    () => props.Information.Direction == 45 || props.Information.Direction == 315
);
/**
 * 指示线是否在底侧
 */
const bottom: ComputedRef<boolean> = computed(
    () => props.Information.Direction == 45 || props.Information.Direction == 135
);

/**
 * 标签左侧边框
 */
const leftBorderColor: ComputedRef<string> = computed(() =>
    right.value ? "0.1rem solid #218CDE" : "0.1rem solid transparent"
);
/**
 * 标签顶侧边框
 */
const topBorderColor: ComputedRef<string> = computed(() =>
    bottom.value ? "0.1rem solid #218CDE" : "0.1rem solid transparent"
);
/**
 * 标签右侧边框
 */
const rightBorderColor: ComputedRef<string> = computed(() =>
    left.value ? "0.1rem solid #218CDE" : "0.1rem solid transparent"
);
/**
 * 标签底侧边框
 */
const bottomBorderColor: ComputedRef<string> = computed(() =>
    top.value ? "0.1rem solid #218CDE" : "0.1rem solid transparent"
);

/**
 * 圆点Margin(用于撑开空间)-左
 */
const leftMargin: ComputedRef<string> = computed(() =>
    left.value
        ? `${props.Information.Length / Math.sqrt(2) - pointEdgeLength * 0.5 - cornerEdgeLength}rem`
        : "0rem"
);
/**
 * 圆点Margin(用于撑开空间)-顶
 */
const topMargin: ComputedRef<string> = computed(() =>
    top.value
        ? `${props.Information.Length / Math.sqrt(2) - pointEdgeLength * 0.5 - cornerEdgeLength + 4}rem`
        : "0rem"
);
/**
 * 圆点Margin(用于撑开空间)-右
 */
const rightMargin: ComputedRef<string> = computed(() =>
    right.value
        ? `${props.Information.Length / Math.sqrt(2) - pointEdgeLength * 0.5 - cornerEdgeLength}rem`
        : "0rem"
);
/**
 * 圆点Margin(用于撑开空间)-底
 */
const bottomMargin: ComputedRef<string> = computed(() =>
    bottom.value
        ? `${props.Information.Length / Math.sqrt(2) - pointEdgeLength * 0.5 - cornerEdgeLength + 4}rem`
        : "0rem"
);

/**
 * 圆点、指示线、标签的排列方向
 */
const flexDirection: ComputedRef<string> = computed(() => left.value ? "row-reverse" : "row");

/**
 * 标签对齐方式(顶对齐或底对齐)
 */
const contentAlign: ComputedRef<string> = computed(() => top.value ? "flex-start" : "flex-end");

/**
 * 标签内容左侧定位
 */
const contentPositionLeft: ComputedRef<string> = computed(() => left.value ? `${pointEdgeLength * 0.5}rem` : `${-pointEdgeLength * 0.5}rem`);
/**
 * 标签内容顶侧定位
 */
const contentPositionTop: ComputedRef<string> = computed(() => top.value ? `${pointEdgeLength * 0.5}rem` : `${-pointEdgeLength * 0.5}rem`);
/**
 * 标签内容水平位移
 */
const contentTranslateX: ComputedRef<string> = computed(() => left.value ? "-100%" : "0%");
/**
 * 标签内容垂直位移
 */
const contentTranslateY: ComputedRef<string> = computed(() => top.value ? "-100%" : "0%");
/**
 * 标签内容位移
 */
const contentTransform: ComputedRef<string> = computed(() => `translate(${contentTranslateX.value}, ${contentTranslateY.value})`);

/**
 * 标签定位-左
 */
const informationPositionLeft: ComputedRef<string> = computed(() => `${props.Information.ViewportPointX}%`);
/**
 * 标签定位-顶
 */
const informationPositionTop: ComputedRef<string> = computed(() => `${props.Information.ViewportPointY}%`);
</script>

<style scoped>
.leader-line-label {
    overflow: visible;

    position: absolute;
    left: v-bind(informationPositionLeft);
    top: v-bind(informationPositionTop);
}

.label-content {
    display: inline-flex;

    flex-direction: v-bind(flexDirection);

    position: absolute;
    left: v-bind(contentPositionLeft);
    top: v-bind(contentPositionTop);

    transform: v-bind(contentTransform);
}

.label-content>input {
    display: none;
}

.location-point {
    display: inline-block;
    width: v-bind(pointEdge);
    height: v-bind(pointEdge);

    margin-left: v-bind(leftMargin);
    margin-top: v-bind(topMargin);
    margin-right: v-bind(rightMargin);
    margin-bottom: v-bind(bottomMargin);

    border-radius: 50%;
    background: linear-gradient(270deg,
            rgba(128, 125, 225, 0.1),
            rgba(33, 140, 222, 0.1));

    position: relative;
}

.location-point::after {
    content: "";
    display: inline-block;
    width: 1rem;
    height: 1rem;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: linear-gradient(90deg, #807de1, #218cde);
}

.location-point::before {
    content: "";
    display: inline-block;
    width: v-bind(lineLength);
    height: 0.1rem;
    position: absolute;
    left: 50%;
    top: 50%;
    transform-origin: left;
    transform: translate(0, -50%) rotateZ(v-bind(lineDirection));
    border-radius: 50%;
    background: #218cde;
}

.content {
    display: inline-block;

    align-self: v-bind(contentAlign);

    background-color: rgba(54, 56, 75, 0.2);
    border-radius: 1rem;

    position: relative;

    pointer-events: auto;
}

.content>span:first-of-type {
    display: inline-block;
    font-size: 2rem;
    font-family: "Source Han Sans CN";
    font-weight: normal;
    color: white;
    line-height: 2rem;

    white-space: nowrap;

    padding: 1rem 2rem;

    background-color: rgba(54, 56, 75, 0.75);
    border-radius: 0.6rem;
}

.label-content>input:checked+.content>span:first-of-type {
    background: linear-gradient(90deg, #807de1, #218cde);
}

.content>span:last-of-type {
    display: inline-block;

    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;

    border-radius: 0.6rem;
    border-left: v-bind(leftBorderColor);
    border-top: v-bind(topBorderColor);
    border-right: v-bind(rightBorderColor);
    border-bottom: v-bind(bottomBorderColor);
}

.content ::before {
    content: "";
    display: inline-block;
    position: absolute;
    left: -1rem;
    top: -1rem;
    right: -1rem;
    bottom: -1rem;

    background-color: rgba(54, 56, 75, 0.2);
    border-radius: 0.6rem;

    z-index: -1;
}
</style>